package com.ruochen.common.base;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.Toast;

import androidx.core.app.ActivityOptionsCompat;
import androidx.databinding.ViewDataBinding;

import com.aries.ui.util.StatusBarUtil;
import com.aries.ui.view.title.TitleBarView;
import com.blankj.utilcode.util.ActivityUtils;
import com.blankj.utilcode.util.AppUtils;
import com.blankj.utilcode.util.StringUtils;
import com.lxj.xpopup.XPopup;
import com.lxj.xpopup.impl.LoadingPopupView;
import com.ruochen.common.R;
import com.ruochen.common.listener.NoDoubleClickListener;
import com.ruochen.common.utils.SerializableSpTools;

import org.greenrobot.eventbus.EventBus;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import es.dmoral.toasty.Toasty;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.observers.DefaultObserver;
import io.reactivex.schedulers.Schedulers;


/**
 * activity 基类
 * createBy JunSong
 */
public abstract class BaseActivity<VB extends ViewDataBinding> extends RxActivity {

    protected VB viewBinding;
//    public TitleBarView titleBar;
    protected BaseActivity mContext;
    protected boolean mIsFirstShow = true;

    protected LoadingPopupView mSVProgressHUD;
    private List<BaseFragment> registFragmentList;

    //是否显示titleBar 底部线
    protected boolean isShowLine() {
        return false;
    }

//    @LayoutRes
//    protected abstract int getLayout();

    protected void beforeSetView(Bundle savedInstanceState) {
    }

    protected void setTitleBar(Bundle savedInstanceState) {
    }

    protected void afterSetView(Bundle savedInstanceState) {
    }

    protected abstract void initView(Bundle var1);

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.mContext = this;
        this.beforeSetView(savedInstanceState);
        Type superclass = getClass().getGenericSuperclass();
        Class<?> aClass = (Class<?>) ((ParameterizedType) superclass).getActualTypeArguments()[0];
        try {
            Method method = aClass.getDeclaredMethod("inflate", LayoutInflater.class);
            viewBinding = (VB) method.invoke(null, getLayoutInflater());
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
        this.setContentView(viewBinding.getRoot());
        initTitle(savedInstanceState);
        this.initView(savedInstanceState);
        this.afterSetView(savedInstanceState);
        if (isRegisterEventBus()) {
            EventBus.getDefault().register(this);
        }
    }

    private void initTitle(Bundle savedInstanceState) {
        StatusBarUtil.setStatusBarLightMode(mContext);
//        titleBar = findViewById(R.id.titleBar);
//        if (titleBar == null) {
//            return;
//        }
//        titleBar.setOnLeftTextClickListener(new NoDoubleClickListener() {
//            @Override
//            public void onNoDoubleClick(View view) {
//                onBackPressed();
//            }
//        });
//        setTitleBar(savedInstanceState);
    }

    /**
     * 是否注册事件分发
     *
     * @return true绑定EventBus事件分发，默认不绑定，子类需要绑定的话复写此方法返回true.
     */
    protected boolean isRegisterEventBus() {
        return false;
    }

    //设置是否冲底部关闭
    protected boolean isFinishToBottom() {
        return false;
    }

    public void startActivity(Intent intent) {
        startActivity(intent, R.anim.slide_in_from_right, R.anim.slide_out_to_left);
    }

    public void startActivity(Intent intent, int enterAnim, int exitAnim) {
        ActivityUtils.startActivity(intent, enterAnim, exitAnim);
    }

    public void startActivity(Context mContext, Class<? extends Activity> activity, Bundle bundle, int enterAnim, int exitAnim) {
        Intent intent = new Intent(mContext, activity);
        if (bundle != null) {
            intent.putExtras(bundle);
        }
        ActivityUtils.startActivity(intent, enterAnim, exitAnim);
    }

    public void startActivity(Class<? extends Activity> activity, Bundle bundle) {
        startActivity(mContext, activity, bundle, R.anim.slide_in_from_right, R.anim.slide_out_to_left);
    }

    public void startActivityForResult(Class<? extends Activity> activity, int requestCode, Bundle bundle, int enterAnim, int exitAnim) {
        Intent intent = new Intent(mContext, activity);
        if (bundle != null) {
            intent.putExtras(bundle);
        }
        startActivityForResult(intent, requestCode, ActivityOptionsCompat.makeCustomAnimation(mContext, enterAnim, exitAnim).toBundle());
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
            overridePendingTransition(enterAnim, exitAnim);
        }
    }

    public void startActivityForResult(Class<? extends Activity> activity, int requestCode, Bundle bundle) {
        startActivityForResult(activity, requestCode, bundle, R.anim.slide_in_from_right, R.anim.slide_out_to_left);
    }

    public void startActivityForResult(Class<? extends Activity> activity, int requestCode) {
        startActivityForResult(activity, requestCode, null, R.anim.slide_in_from_right, R.anim.slide_out_to_left);
    }

    public void startActivityNoAnim(Class<? extends Activity> activity, Bundle bundle) {
        startActivity(mContext, activity, bundle, 0, 0);
    }

    public void startActivity(Class<? extends Activity> activity) {
        startActivity(mContext, activity, null, R.anim.slide_in_from_right, R.anim.slide_out_to_left);
    }

    public void startActivityAnimBottom(Class<? extends Activity> activity) {
        startActivity(mContext, activity, null, R.anim.bottom_in, R.anim.bottom_silent);
    }

    public void startActivityAnimBottom(Class<? extends Activity> activity, Bundle bundle) {
        startActivity(mContext, activity, bundle, R.anim.bottom_in, R.anim.bottom_silent);
    }

    public void startActivityAnimBottomForResult(Class<? extends Activity> activity, int requestCode) {
        startActivityForResult(activity, requestCode, null, R.anim.bottom_in, R.anim.bottom_silent);
    }

    public void startActivityAnimBottomForResult(Class<? extends Activity> activity, int requestCode, Bundle bundle) {
        startActivityForResult(activity, requestCode, bundle, R.anim.bottom_in, R.anim.bottom_silent);
    }

    public View getRootView() {
        return ((ViewGroup) findViewById(android.R.id.content)).getChildAt(0);
    }

    public void registFragment(BaseFragment fragment) {
        if (registFragmentList == null) {
            registFragmentList = new ArrayList<>();
        }
        registFragmentList.add(fragment);
    }

    private long exitTime = 0;

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK
                && event.getAction() == KeyEvent.ACTION_DOWN) {
            boolean isFragmentsCancelRequestOnClickBack = false;
            if (registFragmentList != null && registFragmentList.size() > 0) {
                for (int i = 0; i < registFragmentList.size(); i++) {
                    boolean temp = registFragmentList.get(i).onKeyDown(keyCode, event);
                    if (temp) isFragmentsCancelRequestOnClickBack = true;
                }
            }
            if (isCancelRequestOnClickBack()) {
                if (mSVProgressHUD != null && mSVProgressHUD.isShow()) {
                    mSVProgressHUD.dismiss();
                    mSVProgressHUD = null;
                    return true;
                }
            }
            if (isFragmentsCancelRequestOnClickBack) {
                return true;
            }
            //点击两次退出登录判断
            if (isActivityExitAppTips()) {
                if ((System.currentTimeMillis() - exitTime) > 2000) {
                    showToast("再按一次将退出");
                    exitTime = System.currentTimeMillis();
                } else {
                    AppUtils.exitApp();
                }
                return true;
            }
        }
        return super.onKeyDown(keyCode, event);
    }

    /**
     * 点击返回取消正在请求的对话框
     *
     * @return
     */
    public boolean isCancelRequestOnClickBack() {
        return true;
    }

    /**
     * activity是否具有点击返回按钮提示以后退出app提示
     *
     * @return
     */
    public boolean isActivityExitAppTips() {
        return false;
    }


    @Override
    protected void onDestroy() {
        if (mSVProgressHUD != null) {
            if (mSVProgressHUD.isShow()) mSVProgressHUD.dismiss();
            mSVProgressHUD = null;
        }
        if (isRegisterEventBus() && EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().unregister(this);
        }
        super.onDestroy();
        if (registFragmentList != null) {
            registFragmentList.clear();
            registFragmentList = null;
        }
//        titleBar = null;
        mContext = null;
    }

    public List<BaseFragment> getRegisterFragmentList() {
        return registFragmentList;
    }

    @Override
    protected void onResume() {
        if (this.mIsFirstShow) {
            this.mIsFirstShow = false;
        }
        super.onResume();
    }

    @Override
    public void onBackPressed() {
        finish();
        if (!isFinishToBottom()) {
            overridePendingTransition(R.anim.slide_in_from_left, R.anim.slide_out_to_right);
        } else {
            overridePendingTransition(R.anim.bottom_silent, R.anim.bottom_out);
        }
    }

    public void showToast(int resId) {
        showToast(getResources().getString(resId));
    }

    public void showToast(String text) {
        if (mContext!=null)
        Toasty.normal(mContext, text).show();
    }

    public void showLongToast(String text) {
        if (mContext!=null)
        Toasty.normal(mContext, text, Toast.LENGTH_LONG).show();
    }

    public void showLoading() {
        showLoading("加载中");
    }

    public void showLoading(String waitLabel) {
        if (mSVProgressHUD != null) {
            if (mSVProgressHUD.isShow()) mSVProgressHUD.dismiss();
            mSVProgressHUD = null;
        }
        /*mSVProgressHUD = KProgressHUD.create(this)
                .setCancellable(isCancelRequestOnClickBack())
                .setStyle(KProgressHUD.Style.SPIN_INDETERMINATE)
                .setLabel(waitLabel)
                .setDetailsLabel(null);*/
        mSVProgressHUD = new XPopup.Builder(mContext)
                .dismissOnBackPressed(isCancelRequestOnClickBack())
                .dismissOnTouchOutside(isCancelRequestOnClickBack())
                .hasShadowBg(false)
                .isDestroyOnDismiss(true)
                .asLoading(StringUtils.isTrimEmpty(waitLabel) ? "正在加载中" : waitLabel);
        mSVProgressHUD.show();
    }


    public void hide() {
        if (mSVProgressHUD != null) {
            if (mSVProgressHUD.isShow()) mSVProgressHUD.delayDismiss(300);
            mSVProgressHUD = null;
        }
    }

    public void removeCallBack(ApiCallback callback) {

    }

    public Context getMContext() {
        return mContext;
    }

    /**
     * 设置是否点击屏幕关闭软键盘
     */
    protected boolean isDispatchTouchHideSoftInput() {
        return true;
    }

    /**
     * 重写系统事件分发
     *
     * @param ev
     * @return
     */
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN && isDispatchTouchHideSoftInput()) {
            View v = getCurrentFocus();
            if (isShouldHideInput(v, ev)) {
                InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                if (imm != null) {
                    imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
                    v.clearFocus();
                }
            }
            return super.dispatchTouchEvent(ev);
        }
        // 必不可少，否则所有的组件都不会有TouchEvent了
        if (getWindow().superDispatchTouchEvent(ev)) {
            return true;
        }
        return onTouchEvent(ev);
    }

    /**
     * 返回软键盘是否打开
     *
     * @param v
     * @param event
     * @return
     */
    public boolean isShouldHideInput(View v, MotionEvent event) {
        if (v != null && (v instanceof EditText)) {
            int[] leftTop = {0, 0};
            //获取输入框当前的location位置
            v.getLocationInWindow(leftTop);
            int left = leftTop[0];
            int top = leftTop[1];
            int bottom = top + v.getHeight();
            int right = left + v.getWidth();
            if (event.getX() > left && event.getX() < right
                    && event.getY() > top && event.getY() < bottom) {
                // 点击的是输入框区域，保留点击EditText的事件
                return false;
            } else {
                return true;
            }
        }
        return false;
    }


    public boolean isLogin() {
        return false;
    }

    public String getStringSource(int res) {
        return getString(res);
    }

    public String getUserToken() {
        return "";
    }

    public String getUserId() {
        return "";
    }

    public void gotoLogin() {
        /*startActivityAnimBottom(LoginActivity.class,
                new BundleBuilder().putInt("comeInType", 1).create());*/
    }


    public boolean isFinish() {
        boolean a = mContext == null || mContext.isFinishing();
        if (Build.VERSION.SDK_INT < 17) {
            return a;
        } else {
            return a || mContext.isDestroyed() || mContext.getFragmentManager().isDestroyed();
        }
    }

    public void onBackPressedDelayed(long time, Object result) {
        Observable.just(result)
                .delay(time, TimeUnit.MILLISECONDS)
                .compose(bindToLifecycle())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new DefaultObserver<Object>() {

                    @Override
                    protected void onStart() {
                        super.onStart();
                    }

                    @Override
                    public void onNext(@NonNull Object o) {
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                    }

                    @Override
                    public void onComplete() {
                        onBackPressed();
                    }
                });
    }

}
